<?php
namespace app\common\loglic;

class Tree
{
    /**
     * 对查询结果集进行排序
     * @version 1.0.0 首次引入
     * @param array $list 查询结果
     * @param string $field 排序的字段名
     * @param string $sortby 排序类型 (asc正向排序 desc逆向排序 nat自然排序)
     * @param bool $oldkey 是否保留原key
     * @return array
     */
    public function list_sort_by($list=[], $field='', $sortby='asc', $oldkey=false) {
        if(is_array($list)){
            $refer = $resultSet = array();
            foreach ($list as $i => $data)
                $refer[$i] = &$data[$field];
            switch ($sortby) {
                case 'asc': // 正向排序
                    asort($refer);
                    break;
                case 'desc':// 逆向排序
                    arsort($refer);
                    break;
                case 'nat': // 自然排序
                    natcasesort($refer);
                    break;
            }
            foreach ($refer as $key=> $val){
                if($oldkey){
                    $resultSet[$key] = &$list[$key];
                }else{
                    $resultSet[] = &$list[$key];
                }
            }
            return $resultSet;
        }
        return false;
    }
    
    /*** 
     * 把返回的数据转换成Tree
    * @version 1.0.0 首次引入
    * @param array $list 要转换的数据集
    * @param string $pid parent标记字段
    * @param string $level level标记字段
    * @return array 
    */
    public function list_to_tree($list=[], $pk='id', $pid = 'pid', $child = '_child', $root=0)
    {
        // 创建Tree
        $tree = array();
        if(is_array($list)) {
            // 创建基于主键的数组引用
            $refer = array();
            foreach ($list as $key => $data) {
                $refer[$data[$pk]] =& $list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $parentId = $data[$pid];
                if ($root == $parentId) {
                    $tree[] =& $list[$key];
                }else{
                    if (isset($refer[$parentId])) {
                        $parent =& $refer[$parentId];
                        $parent[$child][] =& $list[$key];
                    }
                }
            }
        }
        return $tree;
    }
    
    /**
     * 将树状还原成带层维数的数据列表/用于表格展示
    * @version 1.0.0 首次引入
    * @param  array $tree  原来的树
    * @param  string $pkName 要添加符号的键名
    * @param  string $level 记录无限层级关系 
    * @param  string $child 孩子节点的键
    * @param  array  $list  过渡用的中间数组，
    * @return array 返回排过序的列表数组
    */
    public function tree_to_level($tree=[], $pkName='', $level=0, $child='_child', &$list = array()){
        if(is_array($tree)) {
            $icon   = '';
            if ($level > 0) {
                $icon = '|';
                for ($i=0; $i < $level; $i++) {
                    $icon .= '─ ';
                }
            }
            $refer = array();
            foreach ($tree as $value) {
                $reffer = $value;
                $reffer['level'] = $level;
                if($pkName){
                    $reffer[$pkName] = $icon.$reffer[$pkName];
                }
                if(isset($reffer[$child])){
                    unset($reffer[$child]);
                    $list[] = $reffer;
                    $this->tree_to_level($value[$child], $pkName, $level+1, $child, $list);
                }else{
                    $list[] = $reffer;
                }
            }
        }
        return $list;
    }
}
